package com.lyz.oss.core;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.util.IOUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

@Log4j2
@RequiredArgsConstructor
public class OssTemplateImpl implements OssTemplate{

    private final AmazonS3 amazonS3;

    @Override
    public void createBucket(String bucketName) {
        if(!amazonS3.doesBucketExistV2(bucketName)){
            amazonS3.createBucket(bucketName);
        }
    }

    @Override
    public List<Bucket> allBuckets() {
        return amazonS3.listBuckets();
    }

    @Override
    public void removeBucket(String bucketName) {
        amazonS3.deleteBucket(bucketName);
    }

    @Override
    public PutObjectResult putObject(String bucketName, String objectName, InputStream stream, String contextType) {
        return this.putObject(bucketName,objectName,stream,this.available(stream),contextType);
    }

    @Override
    public PutObjectResult putObject(String bucketName, String objectName, InputStream stream) {
        return this.putObject(bucketName,objectName,stream, this.available(stream),"application/octet-stream");
    }

    private int available(InputStream stream){
        try {
            return stream.available();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    private PutObjectResult putObject(String bucketName, String objectName, InputStream stream, long size, String contextType){
        byte[] bytes = new byte[0];
        try {
            bytes = IOUtils.toByteArray(stream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(size);
        objectMetadata.setContentType(contextType);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        return amazonS3.putObject(bucketName,objectName,byteArrayInputStream,objectMetadata);
    }

    @Override
    public S3Object object(String bucketName, String objectName) {
        return amazonS3.getObject(bucketName,objectName);
    }

    @Override
    public String objectUrl(String bucketName, String objectName, Integer expires) {

        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH,expires);
        URL url = amazonS3.generatePresignedUrl(bucketName,objectName,calendar.getTime());
        return url.toString();
    }

    @Override
    public void removeObject(String bucketName, String objectName) {
        amazonS3.deleteObject(bucketName,objectName);
    }

    @Override
    public List<S3ObjectSummary> allObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
        ObjectListing objectListing = amazonS3.listObjects(bucketName,prefix);
        return objectListing.getObjectSummaries();
    }
}
